Completed
Push — master ( dc6b63...48675a )
by
unknown
02:10
created

save.js ➔ saveJson   B

Complexity

Conditions 3
Paths 2

Size

Total Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
c 1
b 0
f 0
nc 2
dl 0
loc 25
rs 8.8571
nop 2

1 Function

Rating   Name   Duplication   Size   Complexity  
B save.js ➔ ... ➔ eachRecursive 0 9 6
1
import fse from 'fs-extra'
2
import extend from 'extend'
3
import mkdirp from 'mkdirp'
4
import xss from 'xss'
5
import {Promise} from 'es6-promise'
6
import path from 'path'
7
8
import {
9
  cmsOperations,
10
  cmsData,
11
  config,
12
  Page,
13
  cmsTemplates,
14
  abeExtend,
15
  coreUtils
16
} from '../../'
17
18
export function checkRequired(text, json) {
19
  var regAbe = /{{abe[\S\s].*?key=['|"]([\S\s].*?['|"| ]}})/g
20
  var matches = text.match(regAbe)
21
  var requiredValue = 0
22
  var complete = 0
23
  if(typeof matches !== 'undefined' && matches !== null){
24
    Array.prototype.forEach.call(matches, (match) => {
25
      if(typeof match !== 'undefined' && match !== null) {
26
        
27
        var keyAttr = cmsData.regex.getAttr(match, 'key')
28
        var requiredAttr = cmsData.regex.getAttr(match, 'required')
29
        if(requiredAttr === 'true') {
30
          requiredValue++
31
32
          var minAttr = cmsData.regex.getAttr(match, 'min-length')
33
          minAttr = (minAttr !== '') ? minAttr : 0
34
35
          if(typeof json[keyAttr] !== 'undefined' && json[keyAttr] !== null && json[keyAttr] !== '') {
36
            if(minAttr > 0) {
37
              if(json[keyAttr].length >= minAttr) {
38
                complete++
39
              }
40
            }else {
41
              complete++
42
            }
43
          }
44
        }
45
      }
46
    })
47
  }
48
49
  return Math.round((requiredValue > 0) ? complete * 100 / requiredValue : 100)
50
}
51
52
export function save(url, tplPath, json = null, text = '', type = '', previousSave = null, realType = 'draft', publishAll = false) {
53
  url = coreUtils.slug.clean(url)
54
55
  var p = new Promise((resolve) => {
56
    var isRejectedDoc = false
57
    if(type === 'reject'){
58
      isRejectedDoc = true
59
      url = abeExtend.hooks.instance.trigger('beforeReject', url)
60
      type = 'draft'
61
      realType = 'draft'
62
      url = abeExtend.hooks.instance.trigger('afterReject', url)
63
    }
64
    var tplUrl = cmsData.file.fromUrl(url)
65
    type = type || 'draft'
66
    var pathIso = dateIso(tplUrl, type)
67
    if(typeof previousSave !== 'undefined' && previousSave !== null){
68
      pathIso.jsonPath = path.join(config.root, previousSave.jsonPath.replace(config.root, '')).replace(/-abe-d/, `-abe-${realType[0]}`)
69
      pathIso.htmlPath = path.join(config.root, previousSave.htmlPath.replace(config.root, '')).replace(/-abe-d/, `-abe-${realType[0]}`)
70
    }
71
72
    if (tplPath.indexOf('.') > -1) {
73
      tplPath = tplPath.replace(/\..+$/, '')
74
    }
75
    var tpl = tplPath.replace(config.root, '')
76
77
    var fullTpl = path.join(config.root, config.templates.url, tpl) + '.' + config.files.templates.extension
78
79
    if(typeof json === 'undefined' || json === null) {
80
      json = cmsData.file.get(tplUrl.json.path)
81
    }
82
83
    var ext = {
84
      template: tpl.replace(/^\/+/, ''),
85
      link: tplUrl.publish.link,
86
      complete: 0,
87
      type: type
88
    }
89
    let meta = config.meta.name
90
    json[meta] = extend(json[meta], ext)
91
    var date = cmsData.fileAttr.get(pathIso.jsonPath).d
92
93
    if (publishAll) {
94
      if(typeof json[meta].publish !== 'undefined' && json[meta].publish !== null) {
95
        date = json[meta].publish.date
96
      }
97
    }else {
98
      if(typeof date === 'undefined' || date === null || date === '') {
99
        date = new Date()
100
      }else {
101
        date = new Date(date)
102
      }
103
    }
104
105
    cmsData.metas.add(tpl, json, type, {}, date, realType)
106
107
    if(typeof text === 'undefined' || text === null || text === '') {
108
      text = cmsTemplates.template.getTemplate(fullTpl)
109
    }
110
111
    cmsData.source.getDataList(path.dirname(tplUrl.publish.link), text, json)
112
        .then(() => {
113
114
          json = abeExtend.hooks.instance.trigger('afterGetDataListOnSave', json)
115
          for(var prop in json){
0 ignored issues
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
116
            if(typeof json[prop] === 'object' && Array.isArray(json[prop]) && json[prop].length === 1){
117
              var valuesAreEmpty = true
118
              json[prop].forEach(function (element) {
119
                for(var p in element) {
0 ignored issues
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
120
                  if(element[p] !== ''){
121
                    valuesAreEmpty = false
122
                  }
123
                }
124
              })
125
              if(valuesAreEmpty){
126
                delete json[prop]
127
              }
128
            }
129
          }
130
131
          var obj = {
132
            publishAll:publishAll,
133
            type:type,
134
            template:{
135
              path: fullTpl
136
            },
137
            html: {
138
              path:pathIso.htmlPath
139
            },
140
            json: {
141
              content: json,
142
              path: pathIso.jsonPath
143
            }
144
          }
145
146
          obj = abeExtend.hooks.instance.trigger('beforeSave', obj)
147
148
          obj.json.content[meta].complete = checkRequired(text, obj.json.content)
149
150
          var res = saveJsonAndHtml(tpl.replace(/^\/+/, ''), obj, text)
151
          if (isRejectedDoc) {
152
            res.reject = cmsData.fileAttr.delete(url).replace(path.join(config.root, config.draft.url), '')
153
          }
154
          
155
          abeExtend.hooks.instance.trigger('afterSave', obj)
156
          
157
          cmsTemplates.assets.copy()
158
159
          resolve(res)
160
        }).catch(function(e) {
161
          console.error('Save.js', e)
162
        })
163
  })
164
165
  return p
166
}
167
168
export function saveJsonAndHtml(templateId, obj, html) {
169
  var page = new Page(templateId, html, obj.json.content, true)
170
171
  saveHtml(obj.html.path, page.html)
172
  saveJson(obj.json.path, obj.json.content)
173
174
  return {
175
    json: obj.json.content,
176
    jsonPath: obj.json.path,
177
    html: page.html,
178
    htmlPath: obj.html.path
179
  }
180
}
181
182
export function saveJson(url, json) {
183
  mkdirp.sync(path.dirname(url))
184
185
  if(typeof json.abe_source !== 'undefined' && json.abe_source !== null) {
186
    delete json.abe_source
187
  }
188
189
  var eachRecursive = function (obj) {
190
    for (var k in obj) {
0 ignored issues
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
191
      if (typeof obj[k] === 'object' && obj[k] !== null){
192
        eachRecursive(obj[k])
193
      } else if (typeof obj[k] !== 'undefined' && obj[k] !== null){
194
        obj[k] = xss(obj[k].toString().replace(/"/g, '"'), { 'whiteList': config.htmlWhiteList })
195
      }
196
    }
197
  }
198
199
  eachRecursive(json)
200
201
  fse.writeJsonSync(url, json, {
202
    space: 2,
203
    encoding: 'utf-8'
204
  })
205
  return true
206
}
207
208
export function saveHtml(url, html) {
209
  mkdirp.sync(path.dirname(url))
210
  if(cmsData.fileAttr.test(url) && cmsData.fileAttr.get(url).s !== 'd'){
211
    cmsOperations.remove.olderRevisionByType(cmsData.fileAttr.delete(url), cmsData.fileAttr.get(url).s)
212
  }
213
  fse.writeFileSync(url, html)
214
}
215
216
export function dateIso(tplUrl, type = null) {
217
  var newDateISO
218
  var dateISO
219
  var saveJsonFile = tplUrl.json.path
0 ignored issues
show
Unused Code introduced by
The assignment to variable saveJsonFile seems to be never used. Consider removing it.
Loading history...
220
  var saveFile = tplUrl['draft'].path
0 ignored issues
show
Unused Code introduced by
The assignment to variable saveFile seems to be never used. Consider removing it.
Loading history...
221
  
222
  switch(type) {
223
  case 'draft':
224
    newDateISO = cmsData.revision.removeStatusAndDateFromFileName((new Date().toISOString()))
225
    dateISO = 'd' + newDateISO
226
    break
227
  case 'publish':
228
    saveJsonFile = tplUrl.publish.json
229
    saveFile = tplUrl.publish.path
230
    break
231
  default:
232
    newDateISO = cmsData.revision.removeStatusAndDateFromFileName((new Date().toISOString()))
233
    dateISO = type[0] + newDateISO
234
    break
235
  }
236
237
  if(dateISO) {
238
    saveJsonFile = cmsData.fileAttr.add(saveJsonFile, dateISO)
239
    saveFile = cmsData.fileAttr.add(saveFile, dateISO)
240
  }
241
242
  return {
243
    jsonPath: saveJsonFile,
244
    htmlPath: saveFile
245
  }
246
}